﻿using System;
using System.Linq;
using MyFloridaHouse.DataAccess;
using MyFloridaHouse.libSTO;
using MyFloridaHouse.libSvCommonUtilities;
using MyFloridaHouse.libSvDTO;
using System.Net;
using Microsoft.WindowsAzure.StorageClient;
using System.Collections.Generic;
using Microsoft.WindowsAzure;
using System.IO;

namespace MyFloridaHouse.libServiceBusinessRules
{
    public static class File
    {
        public static FileSTO GetCloudFile(FileInfoDTO fileToGet)
        {
            FileSTO fileSTO = null;

            if (fileToGet == null)
            {
                throw new Exception("GetCloudFile failed: No file specified");
            }

            if (fileToGet.fileType == FileInfoFileType.BLOB)
            {
                fileSTO = GetBlobBinaryFile(fileToGet);
            }
            else
            {
                fileSTO = GetBlobTextFile(fileToGet);
            }
            return fileSTO;
        }
        public static FileSTO GetBlobTextFile(FileInfoDTO fileToGet)
        {
            var results = new FileSTO();

            try
            {
                WebClient webClient = new WebClient();
                byte[] blobFile;
                blobFile = webClient.DownloadData(fileToGet.url);
                System.Text.Encoding enc = System.Text.Encoding.ASCII;
                string myString = enc.GetString(blobFile);
                results.fileInfo = fileToGet;
                results.fileInfo.isCompressed = true;
                results.fileData = CompressionManager.Compress(myString);
            }
            catch (Exception ex)
            {
                //todo: Log exception
                results.errorMessage = ex.Message;
            }
            return results;
        }

        public static FileSTO GetBlobBinaryFile(FileInfoDTO fileToGet)
        {
            var results = new FileSTO();

            try
            {
                WebClient webClient = new WebClient();
                byte[] blobFile;
                blobFile = webClient.DownloadData(fileToGet.url);
                results.fileInfo = fileToGet;
                results.fileInfo.isCompressed = true;
                results.fileData = CompressionManager.Compress(blobFile);
            }
            catch (Exception ex)
            {
                //todo: Log exception
                results.errorMessage = ex.Message;
            }
            return results;
        }

        public static FileInfoSTO GetBlobFileInfo(string directoryName)
        {
            var results = new FileInfoSTO();

            try
            {
                results.directory = directoryName;
                results.files = GetCloudDirectoryBlobInfo(Constants.CloudBlobBaseURL, Constants.CloudBlobContainer, directoryName);
            }
            catch (Exception ex)
            {
                results.errorMessage = ex.Message;
            }
            return results;
        }


        public static List<FileInfoDTO> GetCloudDirectoryBlobInfo(string baseURL, string container, string directory)
        {

            CloudStorageAccount cloudStorageAccount = CloudStorageAccount.FromConfigurationSetting("BlobStorageConnectionString");
            if (cloudStorageAccount == null)
            {
                throw new Exception("MyDistrictBuilder's Cloud Storage access credentials are not set up correctly");
            }
            CloudBlobClient blobClient = cloudStorageAccount.CreateCloudBlobClient();
            CloudBlobDirectory blobDir = blobClient.GetBlobDirectoryReference(container);
            CloudBlobDirectory subDirectory = blobDir.GetSubdirectory(directory);

            var blobList = subDirectory.ListBlobs();

            List<FileInfoDTO> blobFileInfo = new List<FileInfoDTO>();
            foreach (var blobInfo in blobList)
            {
                FileInfoDTO fileInfoEntry = new FileInfoDTO();
                fileInfoEntry.fileType = FileInfoFileType.BLOB;
                fileInfoEntry.directory = directory;
                fileInfoEntry.fileName = "Unable to determine filename";
                try
                {
                    fileInfoEntry.url = blobInfo.Uri.AbsoluteUri;
                    fileInfoEntry.fileName = Path.GetFileName(Uri.UnescapeDataString(fileInfoEntry.url));
                    blobFileInfo.Add(fileInfoEntry);
                }
                catch { }
            }
            return blobFileInfo;
        }

        public static CloudBlobDirectory GetBlobSubDir(string baseURL, string container, string directory)
        {
            CloudBlobClient blobClient = new CloudBlobClient(baseURL);
            CloudBlobDirectory blobDir = blobClient.GetBlobDirectoryReference(container);
            return blobDir.GetSubdirectory(directory);
        }


        public static DateTime GetBlockBlobDateTime(string baseURL, string container, string directory, string fileName)
        {
            CloudBlobDirectory subDirectory = GetBlobSubDir(baseURL, container, directory);
            CloudBlockBlob cloudBlockBlob = subDirectory.GetBlockBlobReference(fileName);
            cloudBlockBlob.FetchAttributes();
            DateTime cloudTimeStampUTC = cloudBlockBlob.Properties.LastModifiedUtc;
            return cloudTimeStampUTC;
        }

        public static bool IsFileStale(DateTime clientTimeStampUTC, string blobBaseURL, string blobContainer, string blobDirectory, string blobFileName)
        {
            if (clientTimeStampUTC == null)
            {
                return true;
            }
            else
            {
                if (clientTimeStampUTC < GetBlockBlobDateTime(blobBaseURL, blobContainer, blobDirectory, blobFileName))
                {
                    return true;
                }
                return false;
            }
        }

        public static int GetBlockBlobRowCount(string baseURL, string container, string directory, string fileName)
        {
            CloudBlobDirectory subDirectory = GetBlobSubDir(baseURL, container, directory);
            CloudBlockBlob cloudBlockBlob = subDirectory.GetBlockBlobReference(fileName);
            cloudBlockBlob.FetchAttributes();
            string rowCountStr = cloudBlockBlob.Metadata[Constants.CloudMetadataRowCountKey] ?? string.Empty;
            int rowCount = -1;
            Int32.TryParse(rowCountStr, out rowCount);
            return rowCount;
        }



    }
}

